from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.utils import timezone

from Core import models
from Core.exception import *
from Site.controller import auth
from Site import forms
from Site.controller.messages import *
from Site.controller.context import *

import uuid
import requests


# session_info = {
#     'user_id': user.id,
#     'user_name': data['name'],
#     'last_login': str(timezone.now()),
#     'ip': request.META.get('REMOTE_ADDR', ''),
#     # 'META': request.META,
# }

def static(request, type, name):
    """静态资源重定向"""
    # return HttpResponseRedirect(f'/static/{type}/{name}')
    # 为了兼容旧版本python，没办法
    return HttpResponseRedirect('/static/{}/{}'.format(type, name))


def index(request):
    ctx = get_ctx(request, 'PassNote')
    ctx['hitokoto_range'] = range(1, 10)

    if 'message' in ctx:
        del ctx['message']

    return render(request, 'index.html', ctx)


def account(request):
    ctx = get_ctx(request, 'Account Overview')
    session = ctx['session'] if ctx['verify'] else None

    if request.method == 'POST':
        form = forms.Account(request.POST)
        if not ctx['verify']:  # 如果没有验证成功则中断
            ctx['message'] = Message('You must login first!', MessageType.warning)
            return render(request, 'account.html', ctx)

        if form.is_valid():
            new_account = form.save()
            session.user.accounts.add(new_account)
            ctx = get_ctx(request, 'Account Overview')
            ctx['message'] = Message('Account has saved.', MessageType.success)
        else:
            ctx['message'] = Message('Form is invalid!', MessageType.danger)
    else:
        form = forms.Account()
        ctx['form'] = form

    return render(request, 'account.html', ctx)


def account_list(request):
    ctx = get_ctx(request, 'Account List')
    session = ctx['session'] if ctx['verify'] else None

    if not ctx['verify']:  # 如果没有验证成功则中断
        ctx['message'] = Message('You must login first!', MessageType.warning)
        return render(request, 'account_list.html', ctx)

    if 'platform' in request.GET:
        platform_name = request.GET.get('platform', '')
        ctx = get_ctx(request, 'Account List of {}'.format(platform_name))
        ctx['accounts'] = get_accounts(request, platform_name)
    else:
        ctx['accounts'] = session.user.accounts.all()

    if request.method == 'POST':
        action = request.POST.get('action', '')
        if action == 'update':
            obj = models.Account.objects.filter(id=request.POST['id']).first() if 'id' in request.POST else None
            form = forms.Account(request.POST, instance=obj if obj is not None else None)
            if form.is_valid():
                form.save()
                ctx['message'] = Message('Account {} has been updated.'.format(request.POST.get('name', '[Empty Account Name]')), MessageType.info)
            else:
                ctx['message'] = Message('form is invalid!', MessageType.danger)
        elif action == 'add':
            form = forms.Account(request.POST)
            if form.is_valid():
                new_account = form.save()
                session.user.accounts.add(new_account)
                ctx['message'] = Message('Account {} has been updated.'.format(request.POST.get('name', '[Empty Account Name]')), MessageType.info)
            else:
                ctx['message'] = Message('form is invalid!', MessageType.danger)

    return render(request, 'account_list.html', ctx)


def account_platform(request):
    ctx = get_ctx(request, 'Account Platform')
    session = ctx['session'] if ctx['verify'] else None

    if request.method == 'POST':
        if not ctx['verify']:  # 如果没有验证成功则中断
            ctx['message'] = Message('You must login first!', MessageType.warning)
            return render(request, 'account_platform.html', ctx)

        name = request.POST.get('name', '')
        platform_filter = models.AccountPlatform.objects.filter(name=name)
        if platform_filter.exists():
            existed_platform = platform_filter.first()
            session.user.account_platforms.add(existed_platform)
            ctx = get_ctx(request, 'Account Platform')
            ctx['message'] = Message('New account platform {} saved.'.format(name), MessageType.success)
        else:
            form = forms.AccountPlatform(request.POST)
            if form.is_valid():
                new_platform = form.save()
                session.user.account_platforms.add(new_platform)
                ctx = get_ctx(request, 'Account Platform')
                ctx['message'] = Message('New account platform {} saved.'.format(name), MessageType.success)
            else:
                ctx['message'] = Message('Form data is invalid!', MessageType.danger)

    return render(request, 'account_platform.html', ctx)


def account_detail(request):
    ctx = get_ctx(request, 'Account Detail')

    if not ctx['verify']:  # 如果没有验证成功则中断
        ctx['message'] = Message('You must login first!', MessageType.warning)
        return render(request, 'account_detail.html', ctx)

    if 'id' in request.GET:
        account_info = get_account(request, request.GET['id'])
        if account_info is not None:
            if 'global_message0' in ctx:
                msg = ctx['global_message']  # 保存消息状态
            ctx = get_ctx(request, 'Detail of {}'.format(account_info.name))
            if 'global_message0' in ctx:
                ctx['global_message'] = msg  # 恢复消息状态
            ctx['hitokoto_range'] = range(1, 8)
            ctx['account'] = account_info
        else:
            ctx['message'] = Message('The account of {} is not exist!'.format(request.GET['id']), MessageType.warning)
    else:
        ctx['message'] = Message('Please specify the account first!', MessageType.danger)

    if request.method == 'POST':
        action = request.POST.get('action', '')
        if action == 'update_account':
            obj = models.Account.objects.filter(id=request.POST['id']).first() if 'id' in request.POST else None
            form = forms.Account(request.POST, instance=obj if obj is not None else None)
            if form.is_valid():
                form.save()
                ctx = get_ctx(request, 'Detail of {}'.format(account_info.name))
                ctx['hitokoto_range'] = range(1, 8)
                ctx['account'] = get_account(request, request.GET['id'])
                ctx['message'] = Message('Account {} has been updated.'.format(request.POST.get('name', '[Empty Account Name]')), MessageType.info)
            else:
                ctx['message'] = Message('form is invalid!', MessageType.danger)
        elif action == 'add_extra':
            account_obj = models.Account.objects.filter(id=request.POST['id']).first() if 'id' in request.POST else None
            form = forms.AccountExtraInfo(request.POST)
            if form.is_valid():
                new_extra = form.save()
                account_obj.extra_info.add(new_extra)
                ctx = get_ctx(request, 'Detail of {}'.format(account_info.name))
                ctx['hitokoto_range'] = range(1, 8)
                ctx['account'] = get_account(request, request.GET['id'])
                ctx['message'] = Message('Extra info {} has been added.'.format(request.POST.get('name', '[Empty Extra Name]')), MessageType.info)
            else:
                ctx['message'] = Message('form is invalid!', MessageType.danger)
        elif action == 'update_extra':
            account_obj = models.Account.objects.filter(id=request.POST['id']).first() if 'id' in request.POST else None
            obj = account_obj.extra_info.filter(pk=request.POST['ext_pk']).first() if 'ext_pk' in request.POST else None
            form = forms.AccountExtraInfo(request.POST, instance=obj if obj is not None else None)
            if form.is_valid():
                form.save()
                ctx = get_ctx(request, 'Detail of {}'.format(account_info.name))
                ctx['hitokoto_range'] = range(1, 8)
                ctx['account'] = get_account(request, request.GET['id'])
                ctx['message'] = Message('Extra info {} has been updated.'.format(request.POST.get('name', '[Empty Extra Name]')), MessageType.info)
            else:
                ctx['message'] = Message('form is invalid!', MessageType.danger)

    return render(request, 'account_detail.html', ctx)


def account_delete(request):
    ctx = get_ctx(request)

    if request.method == 'POST':
        if not ctx['verify']:  # 如果没有验证成功则中断
            set_global_msg(request, ctx['message'].content, MessageType.danger)
            return HttpResponseRedirect(request.POST['redirect'])

        account_id = request.POST.get('id', 0)
        obj = models.Account.objects.filter(id=account_id).first()
        try:
            account_name = obj.name
            obj.delete()
            set_global_msg(request, 'Account {} has been deleted.'.format(account_name), MessageType.info)
        except Exception as e:
            set_global_msg(request, e, MessageType.danger)

    return HttpResponseRedirect(request.POST['redirect'])


def account_extra_delete(request):
    ctx = get_ctx(request)

    if request.method == 'POST':
        if not ctx['verify']:  # 如果没有验证成功则中断
            set_global_msg(request, ctx['message'].content, MessageType.danger)
            return HttpResponseRedirect(request.POST['redirect'])

        ext_pk = request.POST.get('ext_pk', 0)
        obj = models.AccountExtraInfo.objects.filter(pk=ext_pk).first()
        try:
            ext_name = obj.name
            obj.delete()
            set_global_msg(request, 'Account extra info {} has been deleted.'.format(ext_name), MessageType.info)
        except Exception as e:
            set_global_msg(request, e, MessageType.danger)

    return HttpResponseRedirect(request.POST['redirect'])


def sign_in(request):
    ctx = {
        'tokens': {},
        'verify': get_verify(request)
    }
    for item in range(0, 11):
        key = 'token{}u{}'.format(item, uuid.uuid4().hex[:8])
        ctx['tokens'][key] = uuid.uuid4().hex

    if ctx['verify']:  # 如果已登录
        return HttpResponseRedirect('/site')

    if request.method == 'POST':
        form = forms.UserSignIn(request.POST)
        if form.is_valid():
            name = form.cleaned_data['name']
            pwd = form.cleaned_data['password']
            user = models.User()

            try:
                user = models.User.objects.get(name=name)
            except user.DoesNotExist as e:
                msg = Message('User does not exist!!', MessageType.danger)
                return render(request, 'sign-in.html', {'form': forms.UserSignIn(), 'message': msg})
            except Exception as e:
                msg = Message(e, MessageType.warning)
                return render(request, 'sign-in.html', {'form': forms.UserSignIn(), 'message': msg})
            else:
                # 登录成功
                if pwd == user.password:
                    # 更新最后登录时间
                    auth.userinfo_update(user)
                    # 保存用户登录的session信息
                    session_id = auth.session_update(user)
                    # 返回cookie信息
                    request.COOKIES['sessionid'] = session_id
                    request.COOKIES['userid'] = user.id

                    response = HttpResponseRedirect('/site')
                    response.set_cookie('session_id', session_id)
                    response.set_cookie('user_id', user.id)
                    return response
                else:
                    ctx['message'] = Message('User name or password wrong!', MessageType.danger)
                    ctx['form'] = forms.UserSignIn()
                    return render(request, 'sign-in.html', ctx)
        else:
            ctx['form'] = forms.UserSignIn()
            ctx['message'] = Message('form is not valid!', MessageType.warning)
            return render(request, 'sign-up.html', ctx)
    else:
        ctx['form'] = forms.UserSignIn()
        return render(request, 'sign-in.html', ctx)


def sign_up(request):
    ctx = {
        'tokens': {},
        'verify': get_verify(request),
        'form': forms.User()
    }
    for item in range(0, 11):
        key = 'token{}u{}'.format(item, uuid.uuid4().hex[:8])
        ctx['tokens'][key] = uuid.uuid4().hex

    if ctx['verify']:  # 如果已登录
        return HttpResponseRedirect('/site')

    if request.method == 'POST':
        form = forms.User(request.POST)
        if form.is_valid():
            name = form.cleaned_data['name']
            users = models.User.objects.filter(name=name)

            if users.exists():
                ctx['message'] = Message('User name is existed!!', MessageType.warning)
                return render(request, 'sign-up.html', ctx)

            user_info = form.save()

            # user_info = models.User(name=form.cleaned_data['name'],
            #                         nickname=form.cleaned_data['nickname'],
            #                         mail=form.cleaned_data['mail'],
            #                         password=form.cleaned_data['password'])
            # user_info.save()

            # 设置返回消息
            set_global_msg(request, 'Create new account success! Welcome to PassNote.', 'success')

            # 更新最后登录时间
            auth.userinfo_update(user_info)
            # 保存用户登录的session信息
            session_id = auth.session_update(user_info)
            # 返回cookie信息
            request.COOKIES['sessionid'] = session_id
            request.COOKIES['userid'] = user_info.id

            response = HttpResponseRedirect('/site')
            response.set_cookie('session_id', session_id)
            response.set_cookie('user_id', user_info.id)

            return response
        else:
            ctx['message'] = Message('form is not valid!', MessageType.warning)
            return render(request, 'sign-up.html', ctx)
    else:
        return render(request, 'sign-up.html', ctx)


def logout(request):
    ctx = {}

    try:
        auth.logout(request)
        msg = Message('You have log out now!', MessageType.info)
        set_global_msg(request, 'You have log out now!', MessageType.info)
    except Exception as e:
        set_global_msg(request, e, MessageType.danger)

    response = HttpResponseRedirect('/site')
    response.delete_cookie('session_id')
    response.delete_cookie('user_id')
    return response


def privacy(request):
    ctx = get_ctx(request, 'Privacy')
    return render(request, 'privacy.html', ctx)


def terms(request):
    ctx = get_ctx(request, 'Terms')
    return render(request, 'terms.html', ctx)


# todo: 就差这个等待开发的页面了
def unavailable(request):
    ctx = get_ctx(request, 'Wait for developing')
    return render(request, 'unavailable.html', ctx)


def user(request):
    ctx = {
        'subtitle': 'Account',
        'poem': requests.get('http://cloud.deali.cn/poem.php').content.decode('utf-8')
    }

    try:
        session = auth.cookie_verify(request)
        ctx['session_id'] = session.id
        ctx['session'] = session
        ctx['user_info'] = session.user
        ctx['platforms'] = session.user.account_platforms.all()
    except NoCookiesProvide as e:
        ctx['message'] = Message('Please login first!', MessageType.danger)
    except Exception as e:
        ctx['message'] = Message(e, MessageType.alert)

    return render(request, 'user.html', ctx)


def settings(request):
    ctx = get_ctx(request, 'Settings')

    if request.method == 'POST':
        usr = ctx['user_info']
        field = request.POST.get('field', '')
        try:
            if field == 'name':
                user_name = request.POST.get('name', '')
                # 检查用户名不能重复
                if models.User.objects.filter(name=user_name).exists():
                    ctx['message'] = Message('The user name "{}" is existed.'.format(usr.name), MessageType.danger)
                else:
                    usr.name = user_name
                    usr.save()
                    ctx['message'] = Message('New user name "{}" saved.'.format(usr.name), MessageType.success)
            elif field == 'password':
                origin_pwd = request.POST.get('origin_pwd', '')
                new_pwd = request.POST.get('new_pwd', '')
                if origin_pwd == usr.password:
                    usr.password = new_pwd
                    usr.save()
                    ctx['message'] = Message('Your password has been updated.', MessageType.success)
                else:
                    ctx['message'] = Message('The origin password is wrong! Please try again.', MessageType.danger)
            elif field == 'nickname':
                usr.nickname = request.POST.get('nickname', '')
                usr.save()
                ctx['message'] = Message('New nickname "{}" saved.'.format(usr.nickname), MessageType.success)
            elif field == 'mail':
                usr.mail = request.POST.get('mail', '')
                usr.save()
                ctx['message'] = Message('New user mail "{}" saved.'.format(usr.mail), MessageType.success)
        except Exception as e:
            ctx['message'] = Message(e, MessageType.danger)

    return render(request, 'settings.html', ctx)
